/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package neuronalenetzeelearning.view.controlpanel;

import java.io.ByteArrayInputStream;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Random;
import neuronalenetzeelearning.PropertyController.PropertyController;
import neuronalenetzeelearning.model.Edge;
import prefuse.data.Node;
import neuronalenetzeelearning.model.Graph;
import neuronalenetzeelearning.view.IController;
import neuronalenetzeelearning.view.IView;
import javax.swing.JFileChooser;
import neuronalenetzeelearning.dataConnectors.GraphMLDocumentBuilder;
import neuronalenetzeelearning.model.Layer1Node;
import neuronalenetzeelearning.model.Layer2Node;
import prefuse.data.io.DataIOException;
import prefuse.data.io.GraphMLReader;

/**
 *
 * @author Henning Ainödhofer
 * Die Action Listener müssen für alle Buttons einzeln implementiert werden
 */
public class Controller implements IController {

    private HashMap<ControlPanelPage, GraphPanelProperty> panelList;
    private static ControlPanelPage VisiblePanel;
    private static ControlPanelPage LearningRule;
    private Graph graph;
    private GraphTestEditor view;
    private GUITestPanels viewTestPanels;
    private PropertyController propCon;
    private JFileChooser fc;
    private boolean lrbool = false;
    /**
     * Mit der Variable validInputOutputValues wird festegelegt, welche Werte die Input und Outputvektoren 
     * bekommen dürfen. Der Defaultwert ist das Dualsystem:
     * 0 = dual
     * 1 = decimal
     */
    private final int validInputOutputValues = 0;

    Controller(Graph graph, GraphTestEditor gui, final HashMap<ControlPanelPage, GraphPanelProperty> panelList) {
        this.graph = graph;
        this.view = gui;
        this.panelList = panelList;
        this.graph.setController(this);
        this.view.setController(this);
        this.propCon = new PropertyController();

        VisiblePanel = ControlPanelPage.DescriptionGraphPanel;

        panelList.get(ControlPanelPage.DescriptionGraphPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.PropertyGraphPanel;
                view.updateFrame(view, VisiblePanel);
                setGraphToPropertyController();
            }
        });

        panelList.get(ControlPanelPage.DescriptionGraphPanel).loadGraphFromFile.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                fc = new JFileChooser();
                fc.setFileFilter(new MyFilter());
                fc.showOpenDialog(view.getRightPanel());
                File loadGraph = fc.getSelectedFile();
                loadGraphFromFile(loadGraph);
            }
        });

        panelList.get(ControlPanelPage.DescriptionGraphPanel).saveGraphToFile.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                fc = new JFileChooser();
                fc.setFileFilter(new MyFilter());
                String path = "";
                if (e.getSource() == panelList.get(ControlPanelPage.DescriptionGraphPanel).saveGraphToFile) {
                    fc.showSaveDialog(view.getRightPanel());
                    File file = fc.getSelectedFile();
                    path = file.getAbsolutePath();
                    if (!path.contains(".")) {
                        System.out.println(fc.getFileFilter().getDescription());
                        path += fc.getFileFilter().getDescription().substring(1);
                    }
                    System.out.println(path);
                }
                saveGraphToFile(path);
            }
        });

        panelList.get(ControlPanelPage.PropertyGraphPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.DescriptionGraphPanel;
                view.updateFrame(view, VisiblePanel);
                SetPopupEnabled();
            }
        });

        panelList.get(ControlPanelPage.PropertyGraphPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepFunktionPanel;
                view.updateFrame(view, VisiblePanel);
                setThesholdValuesToPropertyController(panelList.get(ControlPanelPage.PropertyGraphPanel));
            }
        });

        panelList.get(ControlPanelPage.StepFunktionPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.LearningRuleChooserPanel;
                view.updateFrame(view, VisiblePanel);
                lrbool = false;
                setStepAndOutputFunktionToPropertyController(panelList.get(ControlPanelPage.StepFunktionPanel));
            }
        });

        panelList.get(ControlPanelPage.LearningRuleChooserPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (panelList.get(ControlPanelPage.LearningRuleChooserPanel) instanceof LearningRuleChooserPanel) {
                    LearningRuleChooserPanel rule = (LearningRuleChooserPanel) panelList.get(ControlPanelPage.LearningRuleChooserPanel);
                    if (rule.getLearningRule() == 0) {
                        VisiblePanel = ControlPanelPage.LearningRuleHebbPanel;
                        LearningRule = ControlPanelPage.LearningRuleHebbPanel;
                        panelList.get(VisiblePanel).updateInputTable();
                        view.updateFrame(view, VisiblePanel);

                    } else if (rule.getLearningRule() == 1) {
                        VisiblePanel = ControlPanelPage.LearningRuleSuperwisedLearningPanel;
                        LearningRule = ControlPanelPage.LearningRuleSuperwisedLearningPanel;
                        panelList.get(VisiblePanel).updateInputTable();
                        panelList.get(VisiblePanel).updateOutputTable();
                        view.updateFrame(view, VisiblePanel);
                    }
                }
                lrbool = false;
                setLearningRuleToPropertyController(panelList.get(LearningRule));
            }
        });

        panelList.get(ControlPanelPage.LearningRuleHebbPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepModeChooserPanel;
                view.updateFrame(view, VisiblePanel);
                panelList.get(ControlPanelPage.NStepPanel).setInputVectorPanel(panelList.get(ControlPanelPage.LearningRuleHebbPanel).getInputTable());
                panelList.get(ControlPanelPage.PassPanel).setInputVectorPanel(panelList.get(ControlPanelPage.LearningRuleHebbPanel).getInputTable());
                panelList.get(ControlPanelPage.StepwisePanel).setInputVectorPanel(panelList.get(ControlPanelPage.LearningRuleHebbPanel).getInputTable());
                panelList.get(ControlPanelPage.StepwisePanel).setOutputVectorPanel(panelList.get(ControlPanelPage.LearningRuleHebbPanel));
                panelList.get(ControlPanelPage.PassPanel).setOutputVectorPanel(panelList.get(ControlPanelPage.LearningRuleHebbPanel));
                panelList.get(ControlPanelPage.NStepPanel).setOutputVectorPanel(panelList.get(ControlPanelPage.LearningRuleHebbPanel));
                setHebbPropertysToPropertyController(panelList.get(ControlPanelPage.LearningRuleHebbPanel));
            }
        });

        panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepModeChooserPanel;
                view.updateFrame(view, VisiblePanel);
                panelList.get(ControlPanelPage.NStepPanel).setInputVectorPanel(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).getInputTable());
                panelList.get(ControlPanelPage.PassPanel).setInputVectorPanel(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).getInputTable());
                panelList.get(ControlPanelPage.StepwisePanel).setInputVectorPanel(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).getInputTable());
                panelList.get(ControlPanelPage.NStepPanel).setTargetVectorPanel(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).getTargetTable());
                panelList.get(ControlPanelPage.PassPanel).setTargetVectorPanel(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).getTargetTable());
                panelList.get(ControlPanelPage.StepwisePanel).setTargetVectorPanel(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).getTargetTable());
                panelList.get(ControlPanelPage.NStepPanel).setOutputVectorPanel(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel));
                panelList.get(ControlPanelPage.PassPanel).setOutputVectorPanel(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel));
                panelList.get(ControlPanelPage.StepwisePanel).setOutputVectorPanel(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel));
                setSuperwisedPropertysToPropertyController(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel));

            }
        });

        panelList.get(ControlPanelPage.StepModeChooserPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (panelList.get(ControlPanelPage.StepModeChooserPanel) instanceof StepModeChooserPanel) {
                    StepModeChooserPanel step = (StepModeChooserPanel) panelList.get(ControlPanelPage.StepModeChooserPanel);
                    if (step.getStepMode() == 0) {
                        VisiblePanel = ControlPanelPage.StepwisePanel;
                        view.updateFrame(view, VisiblePanel);
                        setStepModeToPropertyController(1, (StepwisePanel) panelList.get(ControlPanelPage.StepwisePanel), (NStepPanel) panelList.get(ControlPanelPage.NStepPanel), (PassPanel) panelList.get(ControlPanelPage.PassPanel));
                    } else if (step.getStepMode() == 1) {
                        VisiblePanel = ControlPanelPage.NStepPanel;
                        view.updateFrame(view, VisiblePanel);
                        setStepModeToPropertyController(2, (StepwisePanel) panelList.get(ControlPanelPage.StepwisePanel), (NStepPanel) panelList.get(ControlPanelPage.NStepPanel), (PassPanel) panelList.get(ControlPanelPage.PassPanel));
                    } else if (step.getStepMode() == 2) {
                        VisiblePanel = ControlPanelPage.PassPanel;
                        view.updateFrame(view, VisiblePanel);
                        setStepModeToPropertyController(3, (StepwisePanel) panelList.get(ControlPanelPage.StepwisePanel), (NStepPanel) panelList.get(ControlPanelPage.NStepPanel), (PassPanel) panelList.get(ControlPanelPage.PassPanel));
                    }
                }
            }
        });


        panelList.get(ControlPanelPage.LearningRuleChooserPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepFunktionPanel;
                view.updateFrame(view, VisiblePanel);
                lrbool = true;
            }
        });

        panelList.get(ControlPanelPage.LearningRuleHebbPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.LearningRuleChooserPanel;
                view.updateFrame(view, VisiblePanel);
                lrbool = true;
            }
        });

        panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.LearningRuleChooserPanel;
                view.updateFrame(view, VisiblePanel);
                lrbool = true;
            }
        });

        panelList.get(ControlPanelPage.StepModeChooserPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (panelList.get(ControlPanelPage.StepModeChooserPanel) instanceof StepModeChooserPanel) {
                    if (LearningRule.equals(ControlPanelPage.LearningRuleHebbPanel)) {
                        VisiblePanel = ControlPanelPage.LearningRuleHebbPanel;
                        panelList.get(VisiblePanel).updateInputTable();
                        view.updateFrame(view, VisiblePanel);
                    } else if (LearningRule.equals(ControlPanelPage.LearningRuleSuperwisedLearningPanel)) {
                        VisiblePanel = ControlPanelPage.LearningRuleSuperwisedLearningPanel;
                        panelList.get(VisiblePanel).updateInputTable();
                        panelList.get(VisiblePanel).updateOutputTable();
                        view.updateFrame(view, VisiblePanel);
                    }
                }
            }
        });

        panelList.get(ControlPanelPage.StepwisePanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepModeChooserPanel;
                view.updateFrame(view, VisiblePanel);
            }
        });

        panelList.get(ControlPanelPage.NStepPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepModeChooserPanel;
                view.updateFrame(view, VisiblePanel);
            }
        });

        panelList.get(ControlPanelPage.PassPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepModeChooserPanel;
                view.updateFrame(view, VisiblePanel);
            }
        });

        panelList.get(ControlPanelPage.StepFunktionPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.PropertyGraphPanel;
                view.updateFrame(view, VisiblePanel);
            }
        });

        panelList.get(ControlPanelPage.StepwisePanel).start.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (panelList.get(ControlPanelPage.StepwisePanel).getStep() == 0) {
                    panelList.get(ControlPanelPage.StepwisePanel).matrix.printMatrixToFile(panelList.get(ControlPanelPage.StepwisePanel).getGraph().getWeightMatrix(), panelList.get(ControlPanelPage.StepwisePanel).getPath(), panelList.get(ControlPanelPage.StepwisePanel).getStep(), panelList.get(ControlPanelPage.StepwisePanel).getPropertys());
                }
                calculateWithPropertyController(panelList.get(ControlPanelPage.StepwisePanel));

            }
        });

        panelList.get(ControlPanelPage.NStepPanel).start.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (panelList.get(ControlPanelPage.NStepPanel).getStep() == 0) {
                    panelList.get(ControlPanelPage.NStepPanel).matrix.printMatrixToFile(panelList.get(ControlPanelPage.NStepPanel).getGraph().getWeightMatrix(), panelList.get(ControlPanelPage.NStepPanel).getPath(), panelList.get(ControlPanelPage.NStepPanel).getStep(), panelList.get(ControlPanelPage.NStepPanel).getPropertys());
                }
                calculateWithPropertyController(panelList.get(ControlPanelPage.NStepPanel));
            }
        });

        panelList.get(ControlPanelPage.PassPanel).start.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (panelList.get(ControlPanelPage.PassPanel).getStep() == 0) {
                    panelList.get(ControlPanelPage.PassPanel).matrix.printMatrixToFile(panelList.get(ControlPanelPage.PassPanel).getGraph().getWeightMatrix(), panelList.get(ControlPanelPage.PassPanel).getPath(), panelList.get(ControlPanelPage.PassPanel).getStep(), panelList.get(ControlPanelPage.PassPanel).getPropertys());
                }
                calculateWithPropertyController(panelList.get(ControlPanelPage.PassPanel));


            }
        });

        panelList.get(ControlPanelPage.PropertyGraphPanel).automaticEgdeWeight.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                GenerateEdgeWightValues(panelList.get(ControlPanelPage.PropertyGraphPanel));
            }
        });

        panelList.get(ControlPanelPage.PropertyGraphPanel).automaticThreshold.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                GenerateThresholdValues(panelList.get(ControlPanelPage.PropertyGraphPanel));
            }
        });

        panelList.get(ControlPanelPage.LearningRuleHebbPanel).automaticInputButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                GenerateInputValues(panelList.get(ControlPanelPage.LearningRuleHebbPanel));
            }
        });

        panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).automaticInputButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                GenerateInputValues(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel));
            }
        });

        panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).automaticOutputButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                GenerateOutputValues(panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel));
            }
        });
    }

    Controller(Graph graph, GUITestPanels gui, final HashMap<ControlPanelPage, GraphPanelProperty> panelList) {
        this.graph = graph;
        this.graph.setController(this);
        this.panelList = panelList;
        this.viewTestPanels = gui;
        this.viewTestPanels.setController(this);
        VisiblePanel = ControlPanelPage.DescriptionGraphPanel;

        panelList.get(ControlPanelPage.DescriptionGraphPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.PropertyGraphPanel;
                viewTestPanels.remove(viewTestPanels.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });

        panelList.get(ControlPanelPage.PropertyGraphPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.LearningRuleChooserPanel;
                viewTestPanels.remove(view.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });

        panelList.get(ControlPanelPage.LearningRuleChooserPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (panelList.get(ControlPanelPage.LearningRuleChooserPanel) instanceof LearningRuleChooserPanel) {
                    LearningRuleChooserPanel rule = (LearningRuleChooserPanel) panelList.get(ControlPanelPage.LearningRuleChooserPanel);
                    if (rule.getLearningRule() == 0) {
                        VisiblePanel = ControlPanelPage.LearningRuleHebbPanel;
                        LearningRule = ControlPanelPage.LearningRuleHebbPanel;
                        viewTestPanels.remove(viewTestPanels.getRightPanel());
                        viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                        viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                        viewTestPanels.validate();
                        viewTestPanels.repaint();
                    } else if (rule.getLearningRule() == 1) {
                        VisiblePanel = ControlPanelPage.LearningRuleSuperwisedLearningPanel;
                        LearningRule = ControlPanelPage.LearningRuleSuperwisedLearningPanel;
                        viewTestPanels.remove(viewTestPanels.getRightPanel());
                        viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                        viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                        viewTestPanels.validate();
                        viewTestPanels.repaint();
                    }
                }
            }
        });

        panelList.get(ControlPanelPage.LearningRuleHebbPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepModeChooserPanel;
                viewTestPanels.remove(viewTestPanels.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });

        panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepModeChooserPanel;
                viewTestPanels.remove(viewTestPanels.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });

        panelList.get(ControlPanelPage.StepModeChooserPanel).next.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (panelList.get(ControlPanelPage.StepModeChooserPanel) instanceof StepModeChooserPanel) {
                    StepModeChooserPanel step = (StepModeChooserPanel) panelList.get(ControlPanelPage.StepModeChooserPanel);
                    if (step.getStepMode() == 0) {
                        VisiblePanel = ControlPanelPage.StepwisePanel;
                        viewTestPanels.remove(viewTestPanels.getRightPanel());
                        viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                        viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                        viewTestPanels.validate();
                        viewTestPanels.repaint();
                    } else if (step.getStepMode() == 1) {
                        VisiblePanel = ControlPanelPage.NStepPanel;
                        viewTestPanels.remove(viewTestPanels.getRightPanel());
                        viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                        viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                        viewTestPanels.validate();
                        viewTestPanels.repaint();
                    } else if (step.getStepMode() == 2) {
                        VisiblePanel = ControlPanelPage.PassPanel;
                        viewTestPanels.remove(viewTestPanels.getRightPanel());
                        viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                        viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                        viewTestPanels.validate();
                        viewTestPanels.repaint();
                    }
                }
            }
        });

        panelList.get(ControlPanelPage.PropertyGraphPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                VisiblePanel = ControlPanelPage.DescriptionGraphPanel;
                SetPopupEnabled();
                viewTestPanels.remove(viewTestPanels.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });

        panelList.get(ControlPanelPage.PropertyGraphPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                VisiblePanel = ControlPanelPage.DescriptionGraphPanel;
                SetPopupEnabled();
                viewTestPanels.remove(viewTestPanels.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });

        panelList.get(ControlPanelPage.LearningRuleHebbPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.LearningRuleChooserPanel;
                viewTestPanels.remove(viewTestPanels.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });

        panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.LearningRuleChooserPanel;
                viewTestPanels.remove(viewTestPanels.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });

        panelList.get(ControlPanelPage.StepModeChooserPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (panelList.get(ControlPanelPage.StepModeChooserPanel) instanceof StepModeChooserPanel) {
                    if (LearningRule.equals(ControlPanelPage.LearningRuleHebbPanel)) {
                        VisiblePanel = ControlPanelPage.LearningRuleHebbPanel;
                        viewTestPanels.remove(viewTestPanels.getRightPanel());
                        viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                        viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                        viewTestPanels.validate();
                        viewTestPanels.repaint();
                    } else if (LearningRule.equals(ControlPanelPage.LearningRuleSuperwisedLearningPanel)) {
                        VisiblePanel = ControlPanelPage.LearningRuleSuperwisedLearningPanel;
                        viewTestPanels.remove(viewTestPanels.getRightPanel());
                        viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                        viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                        viewTestPanels.validate();
                        viewTestPanels.repaint();
                    }
                }
            }
        });





        panelList.get(ControlPanelPage.StepwisePanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepModeChooserPanel;
                viewTestPanels.remove(viewTestPanels.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });

        panelList.get(ControlPanelPage.NStepPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepModeChooserPanel;
                viewTestPanels.remove(viewTestPanels.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });

        panelList.get(ControlPanelPage.PassPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.StepModeChooserPanel;
                viewTestPanels.remove(viewTestPanels.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });

        panelList.get(ControlPanelPage.StepFunktionPanel).previous.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                VisiblePanel = ControlPanelPage.PropertyGraphPanel;
                viewTestPanels.remove(viewTestPanels.getRightPanel());
                viewTestPanels.add(panelList.get(VisiblePanel), BorderLayout.EAST);
                viewTestPanels.setRightPanel(panelList.get(VisiblePanel));
                viewTestPanels.validate();
                viewTestPanels.repaint();
            }
        });
    }

    private void setGraphToPropertyController() {
        this.view.disablePopupMenuController();
        this.propCon.setGraph(graph);
        this.propCon.setNodeNumber(this.graph.getLayer2Nodes().size());
        this.propCon.setEdgeNumber(this.graph.getEdges().size());
        panelList.get(ControlPanelPage.DescriptionGraphPanel).setGraph(graph);
        panelList.get(ControlPanelPage.LearningRuleChooserPanel).setGraph(graph);
        panelList.get(ControlPanelPage.LearningRuleChooserPanel).PanelUpdate();
        panelList.get(ControlPanelPage.LearningRuleHebbPanel).setGraph(graph);
        panelList.get(ControlPanelPage.LearningRuleHebbPanel).PanelUpdate();
        panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).setGraph(graph);
        panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).PanelUpdate();
        panelList.get(ControlPanelPage.NStepPanel).setGraph(graph);
        panelList.get(ControlPanelPage.NStepPanel).PanelUpdate();
        panelList.get(ControlPanelPage.PassPanel).setGraph(graph);
        panelList.get(ControlPanelPage.PassPanel).PanelUpdate();
        panelList.get(ControlPanelPage.PropertyGraphPanel).setGraph(graph);
        panelList.get(ControlPanelPage.PropertyGraphPanel).PanelUpdate();
        panelList.get(ControlPanelPage.StepFunktionPanel).setGraph(graph);
        panelList.get(ControlPanelPage.StepFunktionPanel).PanelUpdate();
        panelList.get(ControlPanelPage.StepModeChooserPanel).setGraph(graph);
        panelList.get(ControlPanelPage.StepModeChooserPanel).PanelUpdate();
        panelList.get(ControlPanelPage.StepwisePanel).setGraph(graph);
        panelList.get(ControlPanelPage.StepwisePanel).PanelUpdate();
        //---------------------------------------------------------------------
        panelList.get(ControlPanelPage.HelpPropertyPanel).PanelUpdate();
        panelList.get(ControlPanelPage.HelpPropertyPanel).setGraph(graph);
        panelList.get(ControlPanelPage.HelpLearningRuleChooserPanel).PanelUpdate();
        panelList.get(ControlPanelPage.HelpLearningRuleChooserPanel).setGraph(graph);
    }

    private void SetPopupEnabled() {
        view.enablePopupMenuController();
    }

    private void setThesholdValuesToPropertyController(GraphPanelProperty panel) {
        this.propCon.setThresholdValues((PropertyGraphPanel) panel);
        this.propCon.setEdgeValues((PropertyGraphPanel) panel);
    }

    private void setLearningRuleToPropertyController(GraphPanelProperty panel) {
        this.propCon.setLearningRule(panel, lrbool);
    }

    private void setSuperwisedPropertysToPropertyController(GraphPanelProperty panel) {
        this.propCon.setInputVector((LearningRuleSuperwisedLearningPanel) panel);
        this.propCon.setOutputVector((LearningRuleSuperwisedLearningPanel) panel);
    }

    private void setHebbPropertysToPropertyController(GraphPanelProperty panel) {
        this.propCon.setInputVector((LearningRuleHebbPanel) panel);
    }

    private void setStepModeToPropertyController(int stepmode, StepwisePanel stpan, NStepPanel nstpan, PassPanel passpan) {
        this.propCon.setStepMode(stepmode, stpan, nstpan, passpan);
        this.propCon.resetCount();
    }

    private void setStepAndOutputFunktionToPropertyController(GraphPanelProperty panel) {
        this.propCon.setStepFunktion((StepFunktionPanel) panel, lrbool);
        this.propCon.setOutputFunktion((StepFunktionPanel) panel, lrbool);
        this.propCon.setLearningRate((StepFunktionPanel) panel, lrbool);
    }

    /**
     * Diese Methode startet die Berechnungen mit den angegebenen Einstellungen. Die
     * Schrittseite ist dabei wie folgt gegeben:
     * 0 = Durchlauf
     * 1 = Schrittweise
     * n = n-viele Schritte
     * @param panel
     */
    private void calculateWithPropertyController(GraphPanelProperty panel) {
        if (panel instanceof StepwisePanel) {
            StepwisePanel pan = (StepwisePanel) panel;
            this.propCon.setStepwidth(1);
            this.propCon.calculate(pan);
        } else if (panel instanceof NStepPanel) {
            NStepPanel pan = (NStepPanel) panel;
            this.propCon.setStepwidth(pan.getStepWidth());
            this.propCon.calculate(pan);
        } else if (panel instanceof PassPanel) {
            PassPanel pan = (PassPanel) panel;
            this.propCon.setStepwidth(0);
            this.propCon.calculate(pan);
        }
    }

    private void GenerateEdgeWightValues(GraphPanelProperty panel) {
        PropertyGraphPanel pan = (PropertyGraphPanel) panel;
        for (int i = 0; i < graph.getEdges().size(); i++) {
            pan.getDefaultEdgeTableModel().setValueAt(GenerateRandomValues(-1.0, 1.0), i, 1);
        }
    }

    private void GenerateThresholdValues(GraphPanelProperty panel) {
        PropertyGraphPanel pan = (PropertyGraphPanel) panel;
        for (int i = 0; i < graph.getLayer2Nodes().size(); i++) {
            pan.getDefaultTableModel().setValueAt(GenerateRandomValues(-0.3, 0.3), i, 1);
        }
    }

    private void GenerateInputValues(GraphPanelProperty panel) {
        if (panel instanceof LearningRuleHebbPanel) {
            LearningRuleHebbPanel pan = (LearningRuleHebbPanel) panel;
            for (int j = 0; j < pan.getInputVectorNumber(); j++) {
                for (int i = 0; i < graph.getLayer1Nodes().size(); i++) {
                    pan.getDefaultTableModel().setValueAt(GenerateRandomValues(), i, j + 1);
                }
            }
        } else {
            LearningRuleSuperwisedLearningPanel pan = (LearningRuleSuperwisedLearningPanel) panel;
            for (int j = 0; j < pan.getInputVectorNumber(); j++) {
                for (int i = 0; i < graph.getLayer1Nodes().size(); i++) {
                    pan.getDefaultTableModelInput().setValueAt(GenerateRandomValues(), i, j + 1);
                }
            }
        }

    }

    private void GenerateOutputValues(GraphPanelProperty panel) {
        LearningRuleSuperwisedLearningPanel pan = (LearningRuleSuperwisedLearningPanel) panel;
        for (int j = 0; j < pan.getInputVectorNumber(); j++) {
            for (int i = 0; i < graph.getLayer2Nodes().size(); i++) {
                pan.getDefaultTableModelOutput().setValueAt(GenerateRandomValues(), i, j + 1);
            }
        }
    }

    /**
     * Diese Methode gibt Zufallswerte zurück, die Zwischen der Untergrenze ll und der Obergrenze ul leigen.
     * Eventuell müsste diese Methode nochmal überarbeitet werden um für bessere Zufallszahlen zu sorgen.
     * @param ll
     * @param ul
     * @return
     */
    private double GenerateRandomValues(double ll, double ul) {
        Random RANDOMIZER = new Random();
        DecimalFormat f = new DecimalFormat("#0.00");
        double Ergebnis = ll + (ul - ll) * RANDOMIZER.nextDouble();
        return Math.round(Ergebnis * 100.) / 100.;
    }

    private int GenerateRandomValues() {
        if (this.validInputOutputValues == 0) {
            return Math.round((float) GenerateRandomValues(0, 10) / 10);
        }
        return (int) GenerateRandomValues(0, 9);
    }

    public void loadGraphFromFile(File file) {
        LinkedList<String> graphString = new LinkedList<String>();
        String zeile = "";
        BufferedReader read = null;
        if (file == null) {
            System.out.println("Fehler, Datei konnte nicht gealden werden!");
        } else {
            try {
                read = new BufferedReader(new FileReader(file));
            } catch (IOException ex) {
                System.out.println("Fehler, Datei nicht gefunden!");
            }
            try {
                if (read == null) {
                    System.out.println("Fehler, Datei nicht gefunden");
                } else {
                    Graph loadedGraph = new Graph();
                    while ((zeile = read.readLine()) != null) {
                        graphString.add(zeile);
                    }
                    System.out.println(graphString.size());
                    int stelle = 0;
                    String element = "";
                    for (String test = graphString.get(stelle); !test.equals(":Ende"); test = graphString.get(stelle++)) {
                        if (test.contains("Layer1") || test.contains("Layer2") || test.contains("Edge")) {
                            element = test;
                            continue;
                        } else if (element.contains("Layer1")) {
                            loadedGraph.addNode(new Layer1Node(test));
                            continue;
                        } else if (element.contains("Layer2")) {
                            loadedGraph.addNode(new Layer2Node(test));
                            continue;
                        } else if (element.contains("Edge")) {
                            loadedGraph.addEdge(new Edge(loadedGraph.getNodeByName(test.substring(4, 7)), loadedGraph.getNodeByName(test.substring(11))));
                            continue;
                        }
                    }
                    for (int i = 0; i < loadedGraph.getNodes().size(); i++) {
                        System.out.println(loadedGraph.getNodes().get(i).getName());
                    }
                    for (int i = 0; i < loadedGraph.getEdges().size(); i++) {
                        System.out.println(loadedGraph.getEdges().get(i).getName());
                    }


                    try {
                        String xmlString = (GraphMLDocumentBuilder.convertToGraphMLAsString(loadedGraph));
                        ByteArrayInputStream inputStream = new ByteArrayInputStream(xmlString.getBytes());
                        prefuse.data.Graph g = new GraphMLReader().readGraph(inputStream);
                        view.setG(g);
                        view.getVisualization().reset();
                        view.getVisualization().addGraph("nnel", g);
                        view.updatePopupMenuTestController(view.getVisualization(), g, view, view.getLeftPanel());
                        view.setDataGraph(loadedGraph);
                        view.setGraph(loadedGraph);
                        this.setGraph(loadedGraph);
                        this.propCon.setGraph(loadedGraph);
                        panelList.get(ControlPanelPage.DescriptionGraphPanel).setGraph(loadedGraph);
                        panelList.get(ControlPanelPage.LearningRuleChooserPanel).setGraph(loadedGraph);
                        panelList.get(ControlPanelPage.LearningRuleHebbPanel).setGraph(loadedGraph);
                        panelList.get(ControlPanelPage.LearningRuleSuperwisedLearningPanel).setGraph(loadedGraph);
                        panelList.get(ControlPanelPage.NStepPanel).setGraph(loadedGraph);
                        panelList.get(ControlPanelPage.PassPanel).setGraph(loadedGraph);
                        panelList.get(ControlPanelPage.PropertyGraphPanel).setGraph(loadedGraph);
                        panelList.get(ControlPanelPage.StepFunktionPanel).setGraph(loadedGraph);
                        panelList.get(ControlPanelPage.StepModeChooserPanel).setGraph(loadedGraph);
                        panelList.get(ControlPanelPage.StepwisePanel).setGraph(loadedGraph);
                        view.updateFrame(view, VisiblePanel);
                        System.out.println("Der Graph wurde richtig geladen!");

                    } catch (DataIOException e) {
                        e.printStackTrace();
                        System.err.println("Error loading graph. Exiting...");
                        System.exit(1);
                    }
                    updateView();
                }
            } catch (IOException ex) {
                System.out.println("Fehler beim laden der Datei");
            }
        }
    }

    public void saveGraphToFile(String path) {
        BufferedWriter file = null;
        if (path == null || path.equals("")) {
            System.out.println("Fehler, Dateipfad ist leer!");
        } else {
            try {
                file = new BufferedWriter(new FileWriter(path, true));
            } catch (IOException ex) {
                System.out.println("Fehler, Datei nicht gefunden!");
            }
            try {
                if (file == null) {
                    System.out.println("Fehler");
                } else {
                    file.write("Graphdescription".toUpperCase());
                    file.newLine();
                    file.write(":Layer1Nodes");
                    file.newLine();
                    for (int i = 0; i < graph.getLayer1Nodes().size(); i++) {
                        file.write(graph.getLayer1Nodes().get(i).getName());
                        file.newLine();
                    }
                    file.write(":Layer2Nodes");
                    file.newLine();
                    for (int i = 0; i < graph.getLayer2Nodes().size(); i++) {
                        file.write(graph.getLayer2Nodes().get(i).getName());
                        file.newLine();
                    }
                    file.write(":Edges");
                    file.newLine();
                    for (int i = 0; i < graph.getEdges().size(); i++) {
                        file.write(graph.getEdges().get(i).getName());
                        file.newLine();
                    }
                    file.write(":Ende");
                    file.close();
                }
            } catch (IOException ex) {
                System.out.println("Fehler beim schreiben der Datei");
            }
        }
    }

    @Override
    public void addNode(neuronalenetzeelearning.model.Node node) {
        //both adding node to the graph (datamodel) and the viz (prefuse-graph)
        graph.addNode(node);
        view.addNode(node);
        //repaint everything, doing the update-action
        updateView();
    }

    @Override
    public void updateView() {
        view.recalculatePositions();
        view.getGraphVizPanel().repaint();
        view.getRightPanel().repaint();
        view.repaint();
        view.getVisualization().run("update");
    }

    @Override
    public void changeNodeName(Node node, String newName) {
        node.set("name", newName);
        updateView();
    }

    @Override
    public Graph getGraph() {
        return graph;
    }

    @Override
    public void setGraph(Graph graph) {
        this.graph = graph;
    }

    @Override
    public IView getView() {
        return view;
    }

    @Override
    public void setView(IView view) {
        this.view = (GraphTestEditor) view;
    }

    @Override
    public void addEdge(neuronalenetzeelearning.model.Node from, neuronalenetzeelearning.model.Node to) {
        //edge is added in view first -> action command
        graph.addEdge(new Edge(from, to));
        //repaint everything, doing the update-action
        updateView();
    }

    @Override
    public void deleteEdge(Edge edge) {
        getGraph().deleteEdge(edge);
    }

    @Override
    public void deleteNode(neuronalenetzeelearning.model.Node node) {
        getGraph().deleteNode(node);
    }
}

class MyFilter extends javax.swing.filechooser.FileFilter {

    @Override
    public boolean accept(File file) {
        String filename = file.getName();
        return filename.endsWith(".txt");
    }

    @Override
    public String getDescription() {
        return "*.txt";
    }
    //Input vector Graph->Layer1Node->getValue
}
